﻿using System;
using System.Windows.Forms;
using RestaurantCommon;

namespace Restaurant.Controls
{
    public partial class DinnerRoomUserControl : UserControl
    {
        private Controller _controller;
        private readonly MesaDataSet _dataSet;

        #region Properties

        public Controller Controller
        {
            set
            {
                _controller = value;
                _controller.TableSaved += _controller_TableSaved;
                _controller.TableRequestChanged += _controller_TableRequestChanged;
                SetGridDataSource();
            }
        }
        
        #endregion

        public DinnerRoomUserControl()
        {
            InitializeComponent();
            _dataSet = new MesaDataSet();
            timer.Start();
            timer.Interval = 60000;
            timer.Tick += timer_Tick;
        }

        #region Private Methods

        private void RemoveTables()
        {
            var count = Controls.Count;
            for (var controlIndex = 0; controlIndex < count; controlIndex++)
            {
                var control = Controls[0];
                Controls.Remove(control);
                control.Dispose();
            }
        }

        private static PedidoDataSet.PedidoRow GetRequest(long tableId, PedidoDataSet requests)
        {
            foreach (var request in requests.Pedido)
                if (!request.IsIdMesaNull() && request.IdMesa == tableId && request.Estado != RequestState.Fechado.ToString())
                    return request;
            return null;
        }

        private int DivRem(Control control, out int remainder)
        {
            if(Controls.Count == 0 || Width == 0)
            {
                remainder = 0;
                return 0;
            }
            return Math.DivRem(Controls.Count, Width / (control.Width + 10), out remainder);
        }

        private SingleTableUserControl AddTable(MesaDataSet.MesaRow table, PedidoDataSet.PedidoRow request)
        {
            var control = new SingleTableUserControl
                              {
                                  TableName = table.Nome,
                                  TableNameColor = table.CorNome,
                                  TableBackColor = table.CorFundo,
                                  TableId = table.Id,
                                  Places = table.NumeroLugares
                              };
            if (request != null)
            {
                control.Ocuppy(request.Id, request.DataInicio, request.DataActualizacao, "ADefinir", request.Valor);
                control.RefreshTime(DateTime.Now);
            }
            int remainder;
            var quotient = DivRem(control, out remainder);
            control.Left = remainder * (control.Width + 10) + 10;
            control.Top = quotient * (control.Height + 10) + 10;
            Controls.Add(control);
            return control;
        }

        private void AddTables(MesaDataSet dataSet)
        {
            PedidoDataSet requests = _controller.Requests();            
            foreach (var table in dataSet.Mesa)
            {
                var request = GetRequest(table.Id, requests);
                var tableControl = AddTable(table, request);
                tableControl.Click += tableControl_Click;                
            }
        }

        private void SetGridDataSource()
        {
            _dataSet.Merge(_controller.Tables());            
        }

        private SingleTableUserControl GetTable(long tableId)
        {
            foreach (Control control in Controls)
                if (((SingleTableUserControl)control).TableId == tableId)
                    return (SingleTableUserControl) control;
            return null;            
        }

        private void RefreshTablesTime()
        {
            DateTime now = DateTime.Now;
            foreach (Control control in Controls)
                if (((SingleTableUserControl)control).RequestId.HasValue)
                    ((SingleTableUserControl)control).RefreshTime(now);
        }

        #endregion

        public void RestoreTables()
        {
            RemoveTables();
            AddTables(_dataSet);
        }

        void _controller_TableRequestChanged(object sender, TableEventArgs e)
        {
            var table = GetTable(e.TableId);
            if (table == null)
                return;
            if(e.RequestId.HasValue)
                table.Ocuppy(e.RequestId.Value, e.InitialTime, e.LastChangeTime, e.Stage, e.Value);
            else
                table.Free();
        }
        
        void _controller_TableSaved(object sender, EventArgs e)
        {
            SetGridDataSource();
            RestoreTables();
        }

        void tableControl_Click(object sender, EventArgs e)
        {
            var table = (SingleTableUserControl)sender;
            if (!_controller.ExistsOpenedRequest(this, "Deseja mesmo abrir o pedido?"))
                return;
            if(table.RequestId.HasValue)
                _controller.ShowRequest(table.RequestId.Value);
            else
                _controller.NewRequest(table.TableId, table.Places);
        }

        void timer_Tick(object sender, EventArgs e)
        {
            RefreshTablesTime();
        }
    }
}
